#ifndef MOCHA_DETAIL_EVENTS_H_INCLUDED
#define MOCHA_DETAIL_EVENTS_H_INCLUDED

/**
 * @file 
 */

#include <stdint.h>
#include "mocha/memory.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * Joystick button event.
 */
typedef struct MOCHA_PACKED mocha_joy_button_event {
	int32_t type;
	/// Button state.
	int8_t state;
	/// Button index.
	int8_t button;
} mocha_joy_button_event;
/**
 * Joystick hat (directional pad) event.
 */
typedef struct MOCHA_PACKED mocha_joy_hat_event {
	int32_t type;
	/// Hat position. Either 1, 0, or -1.
	int8_t x, y;
} mocha_joy_hat_event;
/**
 * Joystick axis motion event.
 */
typedef struct MOCHA_PACKED mocha_joy_motion_event {
	int32_t type;
	/// Axis index.
	int8_t axis;
	/// Coordinate of the axis, ranging from the minimum to maximum signed 16-bit integer value.
	int16_t value;
} mocha_joy_motion_event;
/**
 * Keyboard event.
 */
typedef struct MOCHA_PACKED mocha_key_event {
	int32_t type;
	/// Virtual key code.
	int16_t key;
	/// Meta key mask.
	int8_t meta;
} mocha_key_event;
/**
 * Mouse button event.
 */
typedef struct MOCHA_PACKED mocha_mouse_button_event {
	int32_t type;
	/// Button state.
	int8_t state;
	/// Button index.
	int8_t button;
	/// Pointer coordinates (at time of button event).
	int32_t x, y;
} mocha_mouse_button_event;
/**
 * Mouse motion event.
 */
typedef struct MOCHA_PACKED mocha_mouse_motion_event {
	int32_t type;
	/// Pointer coordinates.
	int32_t x, y;
	/// Change in pointer coordinates (delta).
	int32_t dx, dy;
} mocha_mouse_motion_event;
/**
 * Quit event.
 * This event is very important, though it contains no data, and signals some external event that requests the termination of the application.
 * For example, the operating system may terminate the root process, causing this event to appear in the event queue.
 */
typedef struct MOCHA_PACKED mocha_quit_event {
	int32_t type;
} mocha_quit_event;
/**
 * User event.
 * May contain arbitrary (non-type-safe) data.
 * Typically inserted into the event queue manually.
 */
typedef struct MOCHA_PACKED mocha_user_event {
	int32_t type;
	/// User event type. Can be used to identify the use or meaning of the event.
	int32_t user_type;
	/// Opaque pointer to user data.
	void *user_data;
} mocha_user_event;
/**
 * Basic event.
 * Depending on the type, one of the members will be populated with sensible data. All other members should not be read.
 */
typedef union MOCHA_PACKED mocha_event {
	int32_t type;
	mocha_joy_button_event joy_button;
	mocha_joy_hat_event joy_hat;
	mocha_joy_motion_event joy_motion;
	mocha_key_event key;
	mocha_mouse_button_event mouse_button;
	mocha_mouse_motion_event mouse_motion;
	mocha_quit_event quit;
} mocha_event;
/**
 * Event type masks.
 */
typedef enum mocha_event_type_mask {
	mocha_event_joy_button_down = 1 << 0,
	mocha_event_joy_button_up = 1 << 1,
	mocha_event_joy_hat = 1 << 2,
	mocha_event_joy_motion = 1 << 3,
	mocha_event_key_down = 1 << 4,
	mocha_event_key_up = 1 << 5,
	mocha_event_mouse_button_down = 1 << 6,
	mocha_event_mouse_button_up = 1 << 7,
	mocha_event_mouse_motion = 1 << 8,
	mocha_event_quit = 1 << 9,
	mocha_event_user = 1 << 10,
	mocha_event_video_mode = 1 << 11
} mocha_event_type_mask;
/**
 * Generalized event type masks. Useful for generating event filters.
 */
enum {
	mocha_event_joy_button = mocha_event_joy_button_down | mocha_event_joy_button_up,
	mocha_event_joy = mocha_event_joy_button | mocha_event_joy_hat | mocha_event_joy_motion,
	mocha_event_key = mocha_event_key_down | mocha_event_key_up,
	mocha_event_mouse_button = mocha_event_mouse_button_down | mocha_event_mouse_button_up,
	mocha_event_mouse = mocha_event_mouse_button | mocha_event_mouse_motion,
	mocha_event_video = mocha_event_video_mode
};

#ifdef __cplusplus
} // extern "C"
#endif

#endif

